﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Data;
using AccesoDatos;
using System.Configuration;
using ServiciosGeograficos.Modelo;
using System.IO;

/// <summary>
/// Summary description for ServicioCalculoDatos
/// </summary>
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
// To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line. 
// [System.Web.Script.Services.ScriptService]
public class ServicioCalculoDatos : System.Web.Services.WebService
{

    public ServicioCalculoDatos()
    {

        //Uncomment the following line if using designed components 
        //InitializeComponent(); 
    }

    [WebMethod]
    public string MillisecondsToTimeString(double miliAvg)
    {
        TimeSpan demora = TimeSpan.FromMilliseconds(miliAvg);
        return demora.ToString();
    }

    [WebMethod]
    public double[] CalcularDemora(string idLinea, DataSet dsSublineas, int idParada)
    {
        List<double> resultados = new List<double>();
        //int[] sublineas = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24 };
        int[] sublineas = new int[dsSublineas.Tables[0].Rows.Count];
        int i = 0;
        foreach (DataRow rowSublinea in dsSublineas.Tables[0].Rows)
        {
            sublineas[i] = (int)rowSublinea["idSublinea"];
            i++;
        }

        SimuladorPosicion.ServiceSoapClient cliente = new SimuladorPosicion.ServiceSoapClient();

        // Obtener los datos de la parada.
        ServiciosGeograficos.Servicios.Servicios geoSvc = new ServiciosGeograficos.Servicios.Servicios();
        Coordenada coordenadaParada = geoSvc.obtenerCoordenadaParada(idParada);
        double latitudParada = coordenadaParada.Y;//477844.40625;
        double longitudParada = coordenadaParada.X;//6140124.5;

        // Valores de configuracion
        double distanciaPos = double.Parse(ConfigurationManager.AppSettings["distanciaPos"]);
        TimeSpan horaDiff = TimeSpan.Parse(ConfigurationManager.AppSettings["horaDiff"]);

        // Obtengo las posiciones de unidades para esta linea
        DataTable infoLinea = cliente.devolverInformacionLinea(int.Parse(idLinea));

        int dayOfWeekMin = (int)DateTime.Now.DayOfWeek;
        int dayOfWeekMax = dayOfWeekMin;
        TimeSpan horaMax = DateTime.Now.TimeOfDay.Add(horaDiff);
        TimeSpan horaMin = DateTime.Now.TimeOfDay.Subtract(horaDiff);

        if (horaMin.TotalMilliseconds < 0)
        {
            horaMin = (new TimeSpan(23, 59, 59)).Add(horaMin);
            dayOfWeekMin = (dayOfWeekMin - 1) % 7;
        }
        else if (horaMax.Days > 0)
        {
            horaMax = (horaMax.Subtract(new TimeSpan(24, 0, 0)));
            dayOfWeekMax = (dayOfWeekMax + 1) % 7;
        }

        using (EntidadesDataContext edc = new EntidadesDataContext())
        {
            edc.CommandTimeout = int.MaxValue;
            foreach (DataRow unidad in infoLinea.Rows)
            {
                if (sublineas.Contains((int)unidad["codSubLinea"]))
                {
                    var results = edc.ObtenerDemorasHistoricas((double)unidad["y"],
                        (double)unidad["x"], latitudParada, longitudParada, distanciaPos,
                        dayOfWeekMin,
                        dayOfWeekMax,
                        horaMax,
                        horaMin,
                        unidad["sentido"].Equals("A"), (int)unidad["codLinea"]).ToList();

                    var horas = (from r in results
                                 where r.diff.HasValue
                                 select r.diff.Value.TotalMilliseconds).ToList();

                    double miliAvg = -1;
                    if (horas.Count > 0)
                    {
                        miliAvg = horas.Average();
                        resultados.Add(miliAvg);
                    }
                }
            }
        }
        double[] arrayResultados = (from r in resultados
                                    orderby r descending
                                    select r).ToArray();
        return arrayResultados;

    }


    [WebMethod]
    public DatosDemora[] CalcularDemoraConOmnibus(string idLinea, int[] sublineas, int idParada)
    {
        List<DatosDemora> resultado = new List<DatosDemora>();
        //int[] sublineas = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24 };

        SimuladorPosicion.ServiceSoapClient cliente = new SimuladorPosicion.ServiceSoapClient();

        // Obtener los datos de la parada.
        ServiciosGeograficos.Servicios.Servicios geoSvc = new ServiciosGeograficos.Servicios.Servicios();
        Coordenada coordenadaParada = geoSvc.obtenerCoordenadaParada(idParada);
        double latitudParada = coordenadaParada.Y;//477844.40625;
        double longitudParada = coordenadaParada.X;//6140124.5;

        // Valores de configuracion
        double distanciaPos = double.Parse(ConfigurationManager.AppSettings["distanciaPos"]);
        TimeSpan horaDiff = TimeSpan.Parse(ConfigurationManager.AppSettings["horaDiff"]);

        // Obtengo las posiciones de unidades para esta linea
        DataTable infoLinea = cliente.devolverInformacionLinea(int.Parse(idLinea));

        int dayOfWeekMin = (int)DateTime.Now.DayOfWeek;
        int dayOfWeekMax = dayOfWeekMin;
        TimeSpan horaMax = DateTime.Now.TimeOfDay.Add(horaDiff);
        TimeSpan horaMin = DateTime.Now.TimeOfDay.Subtract(horaDiff);

        if (horaMin.TotalMilliseconds < 0)
        {
            horaMin = (new TimeSpan(23, 59, 59)).Add(horaMin);
            dayOfWeekMin = (dayOfWeekMin - 1) % 7;
        }
        else if (horaMax.Days > 0)
        {
            horaMax = (horaMax.Subtract(new TimeSpan(24, 0, 0)));
            dayOfWeekMax = (dayOfWeekMax + 1) % 7;
        }

        using (EntidadesDataContext edc = new EntidadesDataContext())
        {
            foreach (DataRow unidad in infoLinea.Rows)
            {
                if (sublineas.Contains((int)unidad["codSubLinea"]))
                {

                    TextWriter archivoPosicionLinea = new StreamWriter(System.AppDomain.CurrentDomain.BaseDirectory + "datosConsulta.txt", true);
                    archivoPosicionLinea.WriteLine("XUnidad=" + unidad["x"].ToString() +
                        " - YUnidad=" + unidad["y"].ToString() + " - XParada=" + longitudParada + " - YParada=" + latitudParada + " - Diff=" + distanciaPos +
                        " - DayMin=" + dayOfWeekMin +
                        " - DayMax=" + dayOfWeekMax +
                        " - HoraMax=" + horaMax +
                        " - HoraMin=" + horaMin +
                        " - Sentido=" + unidad["sentido"].Equals("A") + " - CodLinea=" + unidad["codLinea"].ToString());
                    archivoPosicionLinea.WriteLine("----------------------------------------------");

                    archivoPosicionLinea.Close();
                    edc.CommandTimeout = int.MaxValue;
                    var results = edc.ObtenerDemorasHistoricas((double)unidad["y"],
                        (double)unidad["x"], latitudParada, longitudParada, distanciaPos,
                        dayOfWeekMin,
                        dayOfWeekMax,
                        horaMax,
                        horaMin,
                        unidad["sentido"].Equals("A"), (int)unidad["codLinea"]).ToList();

                    var horas = (from r in results
                                 where r.diff.HasValue
                                 select r.diff.Value.TotalMilliseconds).ToList();

                    double miliAvg = -1;
                    if (horas.Count > 0)
                    {
                        miliAvg = horas.Average();
                        int idOmnibus = (int)unidad["idOmnibus"];
                        resultado.Add(new DatosDemora(idOmnibus, miliAvg));
                    }
                }
            }
        }

        DatosDemora[] arrayResultado = (from r in resultado
                                        orderby r.MiliSegundos ascending
                                        select r).ToArray();
        return arrayResultado;
    }

    [WebMethod]
    public void prueba()
    {
        System.Diagnostics.Trace.WriteLine("Arranco!");
        String idLinea = "191";
        int[] sublineas = new int[1];
        sublineas[0] = 1;
        int idParadaOrigen = 290;
        DatosDemora[] resultadoOrigen = CalcularDemoraConOmnibus(idLinea, sublineas, idParadaOrigen);
        int idParadaDestino = 409;
        DatosDemora[] resultadoDestino = CalcularDemoraConOmnibus(idLinea, sublineas, idParadaDestino);
        TextWriter archivoPosicionLinea = new StreamWriter(System.AppDomain.CurrentDomain.BaseDirectory + "debugCalculoDemora.txt");
        archivoPosicionLinea.WriteLine("ORIGEN:");
        for (int i = 0; i < resultadoOrigen.Length; i++)
        {
            int minutos = TimeSpan.FromMilliseconds(resultadoOrigen[i].MiliSegundos).Minutes;
            archivoPosicionLinea.WriteLine("Minutos:" + minutos + " IdOmnibus" + resultadoOrigen[i].IdOmnibus);
        }
        archivoPosicionLinea.WriteLine("DESTINO:");
        for (int i = 0; i < resultadoDestino.Length; i++)
        {
            int minutos = TimeSpan.FromMilliseconds(resultadoDestino[i].MiliSegundos).Minutes;
            archivoPosicionLinea.WriteLine("Minutos:" + minutos + " IdOmnibus" + resultadoDestino[i].IdOmnibus);
        }
        archivoPosicionLinea.Close();
    }

}

